using System;
using System.Collections.Generic;
using TXLooker.Common;
using TXLooker.Common.Debuging;
using TXLooker.Common.EventHandling;
using TXLooker.Common.Extentions;
using TXLooker.Core;

namespace TXLooker
{
    /// <summary>
    /// 
    /// </summary>
    internal class ExtentionManager
    {
        #region Loaded Extentions

        /// <summary>
        /// Loaded application extention - IExtentionEntryPoint objects
        /// </summary>
        public ICollection<IExtentionEntryPoint> Extentions
        {
            get { return m_extentions; }
            set { m_extentions = value as List<IExtentionEntryPoint>; }
        }
        private List<IExtentionEntryPoint> m_extentions = new List<IExtentionEntryPoint>();

        #endregion Loaded Extentions

        ExtensionLoader loader = new ExtensionLoader();

        #region Extentions Data Provider

        /// <summary>
        /// Data provider for all extentions
        /// </summary>
        public ExtentionDataProvider DataProvider
        {
            get { return m_extDataProvider; }
            internal set
            {
                if( value == null ) throw new NullReferenceException();
                this.m_extDataProvider = value;
            }
        }
        private ExtentionDataProvider m_extDataProvider;

        #endregion Extentions Data Provider

        #region Class Constructor

        private ExtentionManager()
        { }
        public ExtentionManager( ExtentionDataProvider dataProvider )
        {
            this.DataProvider = dataProvider;
        }

        #endregion Class Constructor

        #region Class Methods

        /// <summary>
        /// Entry Point For Load Extention
        /// </summary>
        public void StartUp(EventSink sink)
        {
            foreach (IExtentionEntryPoint extension in loader.LoadExtensions(ApplicationGlobal.ExtentionDirectiryPath))
            {
                extension.EventSink = sink;
                ItemStart(extension);
            }
        }
        /// <summary>
        /// Unload extention
        /// </summary>
        public void Shutdown()
        {
        lock( this.Extentions )
            {
            foreach( IExtentionEntryPoint item in this.Extentions )
            {
                try
                {
                    item.ShutDown();
                }
                catch( System.Exception ex )
                {
                    string ErrorStr = string.Format("Extention '{0}' Error {1}", item.GetType().ToString(), ex.ToString());
                    LogManager.WriteMessageToCustomLog(ErrorStr);
                    DebugManager.ShowErrorDescription(ErrorStr);
                }

            }
            this.Extentions.Clear();
        }
		}

        private void ItemStart(IExtentionEntryPoint item)
        {
            try
            {
                item.StartUp(this.DataProvider);
                lock (this.Extentions)
                {
                    this.Extentions.Add(item);
                }
            }
            catch (System.Exception ex)
            {
                string ErrorStr = string.Format("Extention '{0}' Error {1}", item.GetType(), ex);
                LogManager.WriteMessageToCustomLog(ErrorStr);
                DebugManager.ShowErrorDescription(ErrorStr);
            }
        }

        #endregion Class Methods
    }


}
